#pragma once

#include <wayland-server.h>
#include <wlr/util/box.h>

#include "server.h"

typedef struct Monitor Monitor;

typedef struct {
    const char *symbol;
    void (*arrange)(Monitor *);
} Layout;

typedef struct {
    const char *name;
    float mfact;
    int nmaster;
    float scale;
    const Layout *lt;
    enum wl_output_transform rr;
} MonitorRule;

typedef struct Monitor
{
    Server *server;
    struct wl_list link;
    struct wlr_output *wlr_output;
    struct wlr_scene_output *scene_output;
    struct wl_listener frame;
    struct wl_listener destroy;
    struct wlr_box m;      /* monitor area, layout-relative */
    struct wlr_box w;      /* window area, layout-relative */
    struct wl_list layers[4]; /* LayerSurface::link */
    const Layout *lt[2];
    unsigned int seltags;
    unsigned int sellt;
    unsigned int tagset[2];
    double mfact;
    int nmaster;
    int un_map; /* If a map/unmap happened on this monitor, then this should be true */
} Monitor;

extern struct wl_list clients; /* tiling order */
extern struct wl_list fstack;  /* focus order */

Monitor* monitor_create(Server* server, struct wlr_output *wlr_output);

void tile(Monitor *m);
void monocle(Monitor *m);
void render_monitor(Monitor* m);
void cleanup_monitor(Monitor* m);
void closemon(Monitor *m);
void arrange(Monitor *m);

Monitor *xytomon(double x, double y, struct wlr_output_layout *output_layout);

/* layout(s) */
static const Layout layouts[] = {
    /* symbol     arrange function */
    { "[]=",      tile },
    { "><>",      NULL },    /* no layout function means floating behavior */
    { "[M]",      monocle },
};

/* monitors */
static const MonitorRule monrules[] = {
    /* name       mfact nmaster scale layout       rotate/reflect */
    /* example of a HiDPI laptop monitor:
    { "eDP-1",    0.5,  1,      2,    &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL },
    */
    /* defaults */
    { NULL,       0.55, 1,      1,    &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL },
};
